#include "graph.hpp"
#include "aco.hpp"
#include "random.hpp"
#include "error.hpp"
#include "distribution.hpp"
#include <cstdio>
#include <cassert>

static long n = -1; 
static long k = -1;
static long r_bound = -1;

bool run_graph_test ( void )
{
        uniform_distribution_c distribution ( 0.0, 0.9999 );
        graph_c * graph = graph_c::generate_random ( n, 0, 0.5, distribution );
        //printf ( "graph: %ld %ld %ld\n", graph->get_nodes_count (), graph->get_edges_count (), graph->get_max_edges_count () );
        for ( long i = 1; i < graph->get_nodes_count (); i ++ )
        {
                /*for ( long j = i + 1; j <= graph->get_nodes_count (); j ++ )
                {
                        const edge_c * edge = graph->get_edge ( i, j );
                        if ( NULL != edge )
                        {
                                printf ( "%ld %ld: %ld %ld %f", i, j, edge->get_first_node_id (), edge->get_second_node_id (), edge->get_probability () );
                                edge->is_rigid () ? printf ( " rigid\n" ) : printf ( "\n" );
                        }
                }*/
        }
        graph->store_dimacs ( "graph_test.col" );

        /*const char test_dimacs_file_name[] = "test_dimacs_file.col";
        const long edges_count = 100, nodes_count = 20;

        FILE * test_dimacs_file = fopen ( test_dimacs_file_name, "w" );
        assert ( NULL != test_dimacs_file );

        fprintf ( test_dimacs_file, "P PEDGE %ld %ld\n", nodes_count, edges_count );
        
        long i;
        long node = 0;
        long node_increment = 1;
        long rigid_edges_count = edges_count / 2;
        double probability = 1.0, probability_modifier = 1.1;

        for ( i = 0; i < edges_count; i ++ )
        {
                fprintf ( test_dimacs_file, "E %ld %ld %f\n", node, node + node_increment, probability );

                ( node < nodes_count - node_increment ) ? node ++ : ( node = 0, node_increment ++ );
                
                if ( i >= rigid_edges_count )
                        probability /= probability_modifier;
        }

        fclose ( test_dimacs_file );

        graph_c * graph = graph_c::parse_dimacs ( test_dimacs_file_name );
        delete graph;*/

        return true;
}

bool run_aco_test ( void )
{
        complex_end_condition_c end_condition ( complex_end_condition_c::LOGICAL_OPERATOR_OR );
        end_condition.set_timeout ( 10 );
        end_condition.set_minimum_threshold ( r_bound );

        aco_c aco ( end_condition );
        aco.load_dimacs_graph ( "graph_test.col" );
        //aco.load_dimacs_graph ( "graphs/min/graph37.5.col" );
        aco.set_r_bound ( r_bound );
        aco.set_k_bound ( k );
        aco.run ();
        aco.flush_dimacs_solution ( "graph_test.col.result" );
        //aco.flush_dimacs_solution ( "boo.result" );

        printf ("Algorithm running time: %ld ms\n", aco.get_running_time_ms () );

        return true;
}

static void set_input_parameters ( long n, long k, long r_bound )
{
        ::n = n;
        ::k = k;
        ::r_bound = r_bound;
}

int main ( int argc, char * argv [] )
{
        try
        {
                long n, k, r_bound;
        
                if ( 1 == argc )
                {
                        n = 20;
                        k = 7;
                        r_bound = 80000;
                }
                else if ( 4 == argc )
                {
                        n = atol ( argv [ 1 ] );
                        k = atol ( argv [ 2 ] );
                        r_bound = atol ( argv [ 3 ] );
                        
                }
                else
                {
                        return -1;
                }
                
                set_input_parameters ( n, k, r_bound );
                printf ( "n = %ld, k = %ld, r_bound = %ld\n", n, k, r_bound );
                
                run_graph_test ();
                run_aco_test ();
        }
        catch ( error_e error_code )
        {
                printf ( "ERROR: %d\n", error_code );
        }
       /* catch ( ... )
        {
                printf ( "ERROR: Unhandled exception\n" );
                throw;
        }*/
        return 0;
}

